using System.Reflection;
using PhillyCodeCamp.Domain;
using PhillyCodeCamp.Domain.Validation;

namespace PhillyCodeCampSpecs.Helpers
{
    public class Person : DomainObject, IPerson
    {
        private string firstName;
        private string lastName;
        private string address;
        private int age;
        private readonly IBusinessRuleSet ruleSet;

        public Person(string firstName, string lastName, string address, int age)
            : this(firstName, lastName, address, age, Rules.Default)
        {

        }

        public Person(string firstName, string lastName, string address, int age, IBusinessRuleSet ruleSet)
            : base(ruleSet)
        {
            this.firstName = firstName;
            this.lastName = lastName;
            this.address = address;
            this.age = age;
            this.ruleSet = ruleSet;
        }

        public string FirstName
        {
            get { return firstName; }
        }

        public string LastName
        {
            get { return lastName; }
        }

        public string Address
        {
            get { return address; }
        }

        public int Age
        {
            get { return age; }
        }

        public sealed class Rules
        {
            private Rules()
            {

            }

            public static IBusinessRule<IPerson> FirstName
            {
                get
                {
                    return new BusinessRule<IPerson>(MethodInfo.GetCurrentMethod().Name, "First name is required", delegate(IPerson person)
                                                                                                                       {
                                                                                                                           return new NonEmptyStringSpecification().IsSatisfiedBy(person.FirstName);
                                                                                                                       });
                }
            }

            public static IBusinessRule<IPerson> LastName
            {
                get
                {
                    return new BusinessRule<IPerson>(MethodInfo.GetCurrentMethod().Name, "Last name is required", delegate(IPerson person)
                                                                                                                      {
                                                                                                                          return new NonEmptyStringSpecification().IsSatisfiedBy(person.LastName);
                                                                                                                      });
                }
            }

            public static IBusinessRule<IPerson> Address
            {
                get
                {
                    return new BusinessRule<IPerson>(MethodInfo.GetCurrentMethod().Name, "Address is required", delegate(IPerson person)
                                                                                                                    {
                                                                                                                        return new NonEmptyStringSpecification().IsSatisfiedBy(person.Address);
                                                                                                                    });
                }
            }

            public static IBusinessRule<IPerson> Age
            {
                get
                {
                    return new BusinessRule<IPerson>(MethodInfo.GetCurrentMethod().Name, "Must be older than 0", delegate(IPerson person)
                                                                                                                     {
                                                                                                                         return person.Age > 0;
                                                                                                                     });
                }
            }

            public static IBusinessRuleSet Default
            {
                get
                {
                    return new BusinessRuleSet<IPerson>(FirstName, LastName, Age, Address);
                }
            }
        }
    }
}